home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / inter54e.zip / INTLIST.E < prev    next >
Text File  |  1997-01-21  |  44KB  |  1,529 lines

  1. /****************************************************************/
  2. /*    EEL code file for editing the Interrupt List        */
  3. /*                                */
  4. /*    Written by Ralf Brown                    */
  5. /*    LastEdit:  21 Jan 97                    */
  6. /*                                */
  7. /*  This EEL file adds the following keybindings:        */
  8. /*    Shf-Alt-A add an Access: section to the current entry    */
  9. /*    Shf-Alt-B add another BUG: to the current entry           */
  10. /*    Shf-Alt-D add a Desc: section to the current entry    */
  11. /*    Sft-Alt-I add an InstallCheck: section to current entry    */
  12. /*    Shf-Alt-R add a Range: section to the current entry       */
  13. /*    Shf-Alt-S add a Size: section to the current entry    */
  14. /*    Alt-I    add an Index: section to the current entry;    */
  15. /*         add another Index: line if already on Index:    */
  16. /*      Alt-N   add a new note to current entry or data struct  */
  17. /*      Alt-P   add a Program: section to the current entry     */
  18. /*      Alt-R   insert Return: at start of line                 */
  19. /*    Alt-S    insert SeeAlso: at start of line; add another    */
  20. /*         SeeAlso: line if already on SeeAlso:        */
  21. /*    F11    insert a blank separator line            */
  22. /*    ^F11    create Format of: header            */
  23. /*    Shf-F11    create Values for: header            */
  24. /*    Alt-F11 create Call with: header            */
  25. /*    Alt-F12 create Bitfield for: header            */
  26. /*    F12    add the interrupt number to the separator line    */
  27. /*        preceding the current entry            */
  28. /*    ^F12    jump to a specified entry            */
  29. /*                                */
  30. /*  It adds the following unbound commands:                */
  31. /*      renumber-tables                            */
  32. /*    make-distribution                    */
  33. /*                                */ 
  34. /*  Other:                            */
  35. /*    adds intlist-mode for .LST and .1ST files        */
  36. /*    switches current buffer into intlist-mode on loading    */
  37. /*      maintains a table counter which is inserted each time   */
  38. /*        a table is created in the text                */
  39. /*      performs syntax highlighting (Epsilon v7+)        */
  40. /****************************************************************/
  41.  
  42. #include "eel.h"
  43. #if EELVERSION >= 70
  44. #include "colcode.h"
  45. #endif /* Epsilon v7.0+ */
  46.  
  47. keytable intlist_tab ;            /* key table for IntList mode */
  48.  
  49. /* on repeated F12, how often to display number of entries processed */
  50. /* for fast 386, every 100; for a Pentium, at least 300 or the message */
  51. /* line will lag way behind the actual progress */
  52. #define NUMBER_INT_PROGRESS_INTERVAL 500
  53.  
  54. /*=============================================================*/
  55. /*    Global Variables                           */
  56. /*=============================================================*/
  57.  
  58. /* table headings */
  59. char str_format_of[] = "Format of " ;
  60. char str_bitfields_for[] = "Bitfields for " ;
  61.  
  62. /* section names within an entry */
  63. char size_section[] = "Size:\t" ;
  64. char access_section[] = "Access:\t" ;
  65. char return_section[] = "Return: " ;
  66. char install_section[] = "InstallCheck:\t" ;
  67. char program_section[] = "Program: " ;
  68. char desc_section[] = "Desc:\t" ;
  69. char range_section[] = "Range:\t" ;
  70. char notes_section[] = "Notes*:\t" ;
  71. char bugs_section[] = "BUGS*:\t" ;
  72. char example_section[] = "Example: " ;
  73. char seealso_section[] = "SeeAlso: " ;
  74. char index_section[] = "Index:\t" ;
  75.  
  76. #if EELVERSION >= 70
  77. char all_sections[] = "Return:|SeeAlso:|Program:|Desc:|Range:|Notes*:|BUGS*:|Example:|Index:|Access:|InstallCheck:|Size:" ;
  78. char indented_sections[] = "[\t ]*(Return|Notes*):" ;
  79. char table_headers[] = "INT |Format |Values |Bitfields |MEM |CMOS |MSR |CALL |PORT |Call |OPCODE " ;
  80. #endif /* Epsilon v7.0+ */
  81.  
  82. char table_ID_letters[] = "0123456789CFMPR" ;
  83.  
  84. char *(section_order[13]) ;
  85. char *(list_files[11]) ;
  86.  
  87. when_loading()
  88. {
  89.    /* list the sections of an entry in the order they should appear (if */
  90.    /* present at all) */
  91.    section_order[0] = size_section ;
  92.    section_order[1] = access_section ;
  93.    section_order[2] = return_section ;
  94.    section_order[3] = install_section ;
  95.    section_order[4] = program_section ;
  96.    section_order[5] = desc_section ;
  97.    section_order[6] = range_section ;
  98.    section_order[7] = notes_section ;
  99.    section_order[8] = bugs_section ;
  100.    section_order[9] = example_section ;
  101.    section_order[10] = seealso_section ;
  102.    section_order[11] = index_section ;
  103.    section_order[12] = NULL ;
  104.    /* list the files comprising the full interrupt list */
  105.    list_files[0] = "cmos.lst" ;
  106.    list_files[1] = "farcall.lst" ;
  107.    list_files[2] = "memory.lst" ;
  108.    list_files[3] = "ports.lst" ;
  109.    list_files[4] = "interrup.lst" ;
  110.    list_files[5] = "tables.lst" ;
  111.    list_files[6] = "msr.lst" ;
  112.    list_files[7] = "biblio.lst" ;
  113.    list_files[8] = "glossary.lst" ;
  114.    list_files[9] = "opcodes.lst" ;
  115.    list_files[10] = NULL ;
  116. }
  117.  
  118. /*=============================================================*/
  119. /*    Buffer-specific variables                       */
  120. /*=============================================================*/
  121.  
  122. buffer spot table_counter ;
  123.  
  124. /*=============================================================*/
  125. /*=============================================================*/
  126.  
  127. int empty_line()
  128. {
  129.    return (character(point-1) == '\n' && character(point) == '\n') ;
  130. }
  131.  
  132. /*=============================================================*/
  133. /*=============================================================*/
  134.  
  135. int is_separator_line()
  136. {
  137.    return (empty_line() || parse_string(1,"--------",NULL)) ;
  138. }
  139.  
  140. /*=============================================================*/
  141. /* search in the specified direction (1 = forward, -1 = back)  */
  142. /* for the next entry separator line                   */
  143. /*=============================================================*/
  144.  
  145. int to_separator_line(dir)
  146. int dir ;
  147. {
  148.    nl_reverse() ;
  149.    return search(dir,"\n--------") ;
  150. }
  151.  
  152. /*=============================================================*/
  153. /* move to the location where the specified section of an      */
  154. /* entry begins (if present) or should begin (if not)           */
  155. /*=============================================================*/
  156.  
  157. int to_section_start(section)
  158. char *section ;
  159. {
  160.    int i, j, len ;
  161.  
  162.    for (i = 0 ; section_order[i] ; i++)
  163.       if (strcmp(section,section_order[i]) == 0)
  164.      break ;
  165.    if (section_order[i])
  166.       {
  167.       while (!is_separator_line())
  168.      {
  169.      for (j = i ; section_order[j] ; j++)
  170.         if (parse_string(1,section_order[j],NULL))
  171.            {
  172.            if ((len = parse_string(1,section,NULL)) != 0)
  173.           {
  174.           point += len ;
  175.           return 1 ;    /* section already exists */
  176.           }
  177.            return 0 ;    /* section nonexistent, but found position */
  178.            }
  179.      if (!nl_forward())
  180.         break ;
  181.      }
  182.       return 0 ;    /* section does not yet exist */
  183.       }
  184.    else
  185.       return 0 ;    /* section not found */
  186. }
  187.  
  188. /*=============================================================*/
  189. /*=============================================================*/
  190.  
  191. int make_section(section,start_entry,name)
  192. char *section, *name ;
  193. int start_entry ;
  194. {
  195.    int start = point ;
  196.  
  197.    if (start_entry)
  198.       {
  199.       if (!to_separator_line(-1))  /* find previous separator line */
  200.      {
  201.      point = start ;
  202.      say("Not in an interrupt entry") ;
  203.      return 0 ;
  204.      }
  205.       }
  206.    else
  207.       {
  208.       to_begin_line() ;
  209.       while (!empty_line() && !parse_string(1,"\n--------",NULL))
  210.      if (!nl_reverse())
  211.         break ;
  212.       }
  213.    point++ ;                 /* skip the newline */
  214.    nl_forward() ;             /* advance to first line of entry */
  215.    if (!to_section_start(section))
  216.       {
  217.       if (name)
  218.      stuff(name) ;
  219.       else
  220.      stuff(section) ;
  221.       stuff("\n") ;
  222.       point-- ;              /* back up over inserted newline */
  223.       return 1 ;
  224.       }
  225.    else
  226.       return 0 ;
  227.    return 2 ;  /* just in case */
  228. }
  229.  
  230. /*=============================================================*/
  231. /*=============================================================*/
  232.  
  233. int pluralize_section(plural)
  234. char plural ;
  235. {
  236.    point -= 3 ;
  237.    if (curchar() != plural)        /* already plural ? */
  238.       {
  239.       point++ ;
  240.       insert(plural) ;
  241.       }
  242.    nl_forward() ;
  243.    while (!is_separator_line() && parse_string(1,"[ \t]",NULL))
  244.       nl_forward() ;
  245.    stuff("\t\n") ;
  246.    point-- ;
  247. }
  248.  
  249. /*=============================================================*/
  250. /* Add "SeeAlso: " to the beginning of the current line unless */
  251. /* it is already present; in that case, insert a fresh line    */
  252. /* containing just a SeeAlso: and position the cursor at the   */
  253. /* end of the new line                           */
  254. /*=============================================================*/
  255.  
  256. command see_also() on intlist_tab[ALT('s')]
  257. {
  258.    to_begin_line() ;
  259.    if (parse_string(1,"SeeAlso: ",NULL) == 0)
  260.       stuff("SeeAlso: ") ;
  261.    else
  262.       {
  263.       nl_forward() ;
  264.       stuff("SeeAlso: \n") ;
  265.       point-- ;
  266.       }
  267. }
  268.  
  269. /*=============================================================*/
  270. /* Add a Desc: section if the current entry does not already   */
  271. /* have one; if there is already a Desc: section, move to the  */
  272. /* start of it                               */
  273. /*=============================================================*/
  274.  
  275. command access() on intlist_tab[ALT('A')]
  276. {
  277.    make_section(access_section,1,NULL) ;
  278. }
  279.  
  280. /*=============================================================*/
  281. /* Add a Desc: section if the current entry does not already   */
  282. /* have one; if there is already a Desc: section, move to the  */
  283. /* start of it                               */
  284. /*=============================================================*/
  285.  
  286. command desc() on intlist_tab[ALT('D')]
  287. {
  288.    make_section(desc_section,1,NULL) ;
  289. }
  290.  
  291. /*=============================================================*/
  292. /* Add a InstallCheck: section if the current entry does not   */
  293. /* already have one; if there is already a InstallCheck:       */
  294. /* section, move to the start of it                   */
  295. /*=============================================================*/
  296.  
  297. command instcheck() on intlist_tab[ALT('I')]
  298. {
  299.    make_section(install_section,1,NULL) ;
  300. }
  301.  
  302. /*=============================================================*/
  303. /* Add a Range: section if the current entry does not already  */
  304. /* have one; if there is already a Range: section, move to the */
  305. /* start of it                               */
  306. /*=============================================================*/
  307.  
  308. command range() on intlist_tab[ALT('R')]
  309. {
  310.    make_section(range_section,1,NULL) ;
  311. }
  312.  
  313. /*=============================================================*/
  314. /* Add a Size: section if the current entry does not already   */
  315. /* have one; if there is already a Size: section, move to the  */
  316. /* start of it                               */
  317. /*=============================================================*/
  318.  
  319. command memsize() on intlist_tab[ALT('S')]
  320. {
  321.    make_section(size_section,1,NULL) ;
  322. }
  323.  
  324. /*=============================================================*/
  325. /* Add a "Program: " section to the current entry if it does   */
  326. /* not have one; otherwise, move to the beginning of the       */
  327. /* Program: section                           */
  328. /*=============================================================*/
  329.  
  330. command program() on intlist_tab[ALT('p')]
  331. {
  332.    make_section(program_section,1,NULL) ;
  333. }
  334.  
  335. /*=============================================================*/
  336. /* Add an "Index: " section to the current entry if it does    */
  337. /* not have one; otherwise, move to the beginning of the       */
  338. /* Index: section                           */
  339. /*=============================================================*/
  340.  
  341. command add_index() on intlist_tab[ALT('i')]
  342. {
  343.    to_begin_line() ;
  344.    if (parse_string(1,"Index:",NULL))
  345.       {
  346.       while (parse_string(1,"Index:",NULL))
  347.      nl_forward() ;
  348.       stuff("Index:\t\n") ;
  349.       point-- ;
  350.       }
  351.    else
  352.       make_section(index_section,1,NULL) ;
  353. }
  354.  
  355. /*=============================================================*/
  356. /*=============================================================*/
  357.  
  358. command bug() on intlist_tab[ALT('B')]
  359. {
  360.    if (!make_section(bugs_section,1,"BUG:\t"))
  361.       pluralize_section('S') ;
  362. }
  363.  
  364. /*=============================================================*/
  365. /* Add "Note: " section to the current entry; change an        */
  366. /* existing Note: to Notes: and position at end of Note:       */
  367. /* section.                               */
  368. /*=============================================================*/
  369.  
  370. command add_note() on intlist_tab[ALT('n')]
  371. {
  372.    if (!make_section(notes_section,0,"Note:\t"))
  373.       pluralize_section('s') ;
  374. }
  375.  
  376. /*=============================================================*/
  377. /* Insert "Return: " at the beginning of the current line, if  */
  378. /* not already present                           */
  379. /*=============================================================*/
  380.  
  381. command returns() on intlist_tab[ALT('r')]
  382. {
  383.    int start = point ;
  384.    
  385.    to_begin_line() ;
  386.    if (parse_string(1,return_section,NULL) == 0)
  387.       stuff(return_section) ;
  388.    else
  389.       point = start ;
  390. }
  391.  
  392. /*=============================================================*/
  393. /* insert a line of dashes prior to the current cursor line    */
  394. /*=============================================================*/
  395.  
  396. command separator_line() on intlist_tab[FKEY(11)]
  397. {
  398.    int i ;
  399.  
  400.    to_begin_line() ;
  401.    for (i = 0 ; i < 45 ; i++)
  402.       insert('-') ;
  403.    insert('\n') ;
  404. }
  405.  
  406. /*=============================================================*/
  407. /*=============================================================*/
  408.  
  409. void insert_table_counter()
  410. {
  411.    char counter[6] ;
  412.    save_var point = *table_counter + 3 ;
  413.  
  414.    /* increment that table counter */
  415.    while (curchar() >= '0')
  416.       {
  417.       if (curchar() < '9')
  418.      {
  419.      replace(point,curchar()+1) ;
  420.      break ;
  421.      }
  422.       else
  423.      {
  424.      replace(point,'0') ;
  425.      point-- ;
  426.      }
  427.       }
  428.    restore_vars() ;
  429.    /* and now insert the incremented value at point */
  430.    stuff("(Table ") ;
  431.    grab(*table_counter,*table_counter+4,counter) ;
  432.    stuff(counter) ;
  433.    stuff(")") ;
  434. }
  435.  
  436. /*=============================================================*/
  437. /* type the name of a structure, then invoke this function     */
  438. /* to create the "Format of X:" and "Offset Size Descr" lines  */
  439. /*=============================================================*/
  440.  
  441. command structure_header() on intlist_tab[FCTRL(11)]
  442. {
  443.    int start = point ;
  444.  
  445.    to_begin_line() ;
  446.    if (parse_string(1,str_format_of,NULL) == 0)
  447.       {
  448.       stuff(str_format_of) ;
  449.       to_end_line() ;
  450.       stuff(":\nOffset\tSize\tDescription\t") ;
  451.       insert_table_counter() ;
  452.       stuff("\n 00h\t") ;
  453.       }
  454.    else
  455.       point = start ;
  456. }
  457.  
  458. /*=============================================================*/
  459. /* Turn the current line into the header for a "Values of"     */
  460. /* section                               */
  461. /*=============================================================*/
  462.  
  463. command value_header() on intlist_tab[FSHIFT(11)]
  464. {
  465.    int start = point ;
  466.    
  467.    to_begin_line() ;
  468.    if (parse_string(1,"Values for ",NULL) == 0)
  469.       {
  470.       insert_table_counter() ;
  471.       stuff("\nValues for ") ;
  472.       to_end_line() ;
  473.       stuff(":\n ") ;
  474.       }
  475.    else
  476.       point = start ;
  477. }
  478.  
  479. /*=============================================================*/
  480. /* Turn the current line into the header of a "Call with"      */
  481. /* section                               */
  482. /*=============================================================*/
  483.  
  484. command call_with_header() on intlist_tab[FALT(11)]
  485. {
  486.    int start = point ;
  487.    
  488.    to_begin_line() ;
  489.    if (parse_string(1,"Call ",NULL) == 0)
  490.       {
  491.       insert_table_counter() ;
  492.       stuff("\nCall ") ;
  493.       to_end_line() ;
  494.       if (character(point-1) != ' ')
  495.      stuff(" ") ;
  496.       stuff("with:\n") ;
  497.       }
  498.    else
  499.       point = start ;
  500. }
  501.  
  502. /*=============================================================*/
  503. /* Turn the current line into the header of a "Bitfield for"   */
  504. /* section                               */
  505. /*=============================================================*/
  506.  
  507. command bitfields_for_header() on intlist_tab[FALT(12)]
  508. {
  509.    int start = point ;
  510.    
  511.    to_begin_line() ;
  512.    if (parse_string(1,str_bitfields_for,NULL) == 0)
  513.       {
  514.       stuff(str_bitfields_for) ;
  515.       to_end_line() ;
  516.       stuff(":\nBit(s)\tDescription\t") ;
  517.       insert_table_counter() ;
  518.       stuff("\n ") ;
  519.       }
  520.    else
  521.       point = start ;
  522. }
  523.  
  524. /*=============================================================*/
  525. /*=============================================================*/
  526.  
  527. char grab_int_entry_number(func_num)
  528. char *func_num ;
  529. {
  530.    int i ;
  531.    char c ;
  532.    
  533.    point += 4 ;                /* skip the "INT " */
  534.    func_num[0] = curchar() ;        /* grab the interrupt number */
  535.    point++ ;
  536.    func_num[1] = curchar() ;
  537.    nl_forward() ;            /* skip to second line of entry */
  538.    if (parse_string(1,"[ \t]*A[LHX][ \t]=[ \t][0-9A-F][0-9A-F]+h",NULL))
  539.       {
  540.       re_search(1,"[ \t]*A") ;
  541.       c = curchar() ;
  542.       point += 4 ;            /* skip ch and " = " */
  543.       if (c != 'L')
  544.      {
  545.      grab(point,point+((c=='X')?4:2),func_num+2) ;
  546.      point += ((c=='X')?4:2) ;
  547.      func_num[(c=='H')?4:6] = '-' ;    /* grab() stuck a NUL into the string */
  548.      }
  549.       else /* c == 'L' */
  550.      {
  551.      func_num[4] = curchar() ;
  552.      point++ ;
  553.      func_num[5] = curchar() ;
  554.      point ++ ;
  555.      }
  556.       point++ ;
  557.       if (parse_string(1,"[ \t]*subfn [0-9A-F][0-9A-F]+h",NULL))
  558.      {
  559.      re_search(1,"[ \t]*subfn ") ;
  560.      func_num[6] = 'S' ;
  561.      func_num[7] = 'F' ;
  562.      for (i = 0 ; i < 4 ; i++)
  563.         {
  564.         c = curchar() ;
  565.         if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
  566.            {
  567.            func_num[8+i] = c ;
  568.            point++ ;
  569.            }
  570.         else
  571.            break ;
  572.         }
  573.      }
  574.       nl_forward() ;            /* skip to third line of entry */
  575.       }
  576.    if (parse_string(1,"[ \t]*([BCDES][HILPSX]|VxD) = [0-9A-F][0-9A-F]+h",NULL))
  577.       {
  578.       re_search(1,"[ \t]*") ;
  579.       func_num[6] = curchar() ;
  580.       point++ ;
  581.       func_num[7] = c = curchar() ;
  582.       point += 4 ;            /* skip curchar and " = " */
  583.       if (func_num[6] == 'V')        /* VxD has three letters not two... */
  584.      point++ ;
  585.       if (c == 'H' || c == 'L')
  586.      {
  587.      grab(point,point+2,func_num+8) ;
  588.      func_num[10] = '-' ;        /* grab() stuck a NUL into the string */
  589.      }
  590.       else /* c == 'X' || c == 'I' || c == 'P' || c == 'S' */
  591.      grab(point,point+4,func_num+8) ;
  592.       }
  593.    return 1 ;                /* successful and have func number */
  594. }
  595.  
  596. /*=============================================================*/
  597.  
  598. char grab_cmos_entry_number(func_num)
  599. char *func_num ;
  600. {
  601.    point += 5 ;                    /* skip the "CMOS " */
  602.    func_num[0] = 'R' ;            /* mark this as a CMOS RAM entry */
  603.    grab(point,point+4,func_num+1) ;
  604.    if (func_num[3] == 'h' && func_num[4] == '-')
  605.       grab(point+4,point+6,func_num+3) ;
  606.    else
  607.       {
  608.       func_num[3] = '-' ;
  609.       func_num[4] = '-' ;
  610.       }
  611.    func_num[5] = '-' ;            /* grab() stuck a NUL into string */
  612.    return 1 ;
  613. }
  614.  
  615. /*=============================================================*/
  616.  
  617. char grab_farcall_entry_number(func_num)
  618. char *func_num ;
  619. {
  620.    point += 5 ;                /* skip the "CALL " */
  621.    func_num[0] = '@' ;            /* mark this as a far call entry */
  622.    grab(point,point+4,func_num+1) ;    /* get segment of address */
  623.    grab(point+6,point+10,func_num+5) ;    /* get offset of address */
  624.    func_num[9] = '-' ;            /* grab() stuck a NUL into string */
  625.    return 1 ;
  626. }
  627.  
  628. /*=============================================================*/
  629.  
  630. char grab_msr_entry_number(func_num)
  631. char *func_num ;
  632. {
  633.    point += 4 ;                /* skip the "MSR " */
  634.    func_num[0] = 'S' ;            /* mark this as an MSR entry */
  635.    grab(point,point+8,func_num+1) ;     /* get the MSR number */
  636.    func_num[9] = '-' ;                  /* grab() stuck a NUL into string */
  637.    return 1 ;
  638. }
  639.  
  640. /*=============================================================*/
  641.  
  642. char grab_memory_entry_number(func_num)
  643. char *func_num ;
  644. {
  645.    point += 4 ;                /* skip the "MEM " */
  646.    func_num[0] = 'M' ;                /* mark this as a memory loc entry */
  647.    grab(point,point+6,func_num+1) ;    /* get segment or high word of addr */
  648.    if (func_num[5] == 'h' && func_num[6] == ':') /* segmented address? */
  649.       grab(point+6,point+10,func_num+5) ;    /* get offset of address */
  650.    else
  651.       {
  652.       grab(point+6,point+8,func_num+7) ;/* get low word of the address */
  653.       func_num[0] = 'm' ;        /* indicate linear address */
  654.       }
  655.    func_num[9] = '-' ;            /* grab() stuck a NUL into string */
  656.    return 1 ;
  657. }
  658.  
  659. /*=============================================================*/
  660.  
  661. char grab_opcode_name(func_num)
  662. char *func_num ;
  663. {
  664.    int i ;
  665.    point += 7 ;                /* skip the "OPCODE " */
  666.    func_num[0] = 'O' ;            /* mark this as an opcode entry */
  667.    for (i = 2 ; i < 12 ; i++)        /* grab the opcode name and stuff */
  668.       {                       /*   it into the header line */
  669.       char c = curchar() ;
  670.       if (c == ' ' || c == '\t')
  671.      break ;
  672.       else
  673.      {
  674.      func_num[i] = c ;
  675.      point++ ;
  676.      }
  677.       }
  678.    return 1 ;
  679. }
  680.  
  681. /*=============================================================*/
  682.  
  683. char grab_port_entry_number(func_num)
  684. char *func_num ;
  685. {
  686.    point += 5 ;                /* skip the "PORT " */
  687.    func_num[0] = 'P' ;            /* mark this as an I/O port entry */
  688.    grab(point,point+4,func_num+1) ;    /* get starting port number */
  689.    func_num[5] = '-' ;            /* grab() stuck a NUL into string */
  690.    if (character(point+4) == '-')
  691.       {
  692.       grab(point+5,point+9,func_num+5) ; /* get ending port number */
  693.       func_num[9] = '-' ;        /* grab() stuck a NUL into string */
  694.       }
  695.    return 1 ;
  696. }
  697.  
  698. /*=============================================================*/
  699.  
  700. char grab_entry_number(func_num)
  701. char *func_num ;
  702. {
  703.    strcpy(func_num,"------------") ;    /* 12 dashes */
  704.    point++ ;                /* go to first char of separator line */
  705.    nl_forward() ;            /* go to first line of entry */
  706.    if (parse_string(1,"INT ",NULL))    /* is it an interrupt entry? */
  707.       return grab_int_entry_number(func_num) ;
  708.    else if (parse_string(1,"CMOS ",NULL) != 0)
  709.       return grab_cmos_entry_number(func_num) ;
  710.    else if (parse_string(1,"CALL ",NULL) != 0)
  711.       return grab_farcall_entry_number(func_num) ;
  712.    else if (parse_string(1,"MEM ",NULL) != 0)
  713.       return grab_memory_entry_number(func_num) ;
  714.    else if (parse_string(1,"PORT ",NULL) != 0)
  715.       return grab_port_entry_number(func_num) ;
  716.    else if (parse_string(1,"MSR ",NULL) != 0)
  717.       return grab_msr_entry_number(func_num) ;
  718.    else if (parse_string(1,"OPCODE ",NULL) != 0)
  719.       return grab_opcode_name(func_num) ;
  720.    else
  721.       return 0 ;
  722. }
  723.  
  724. /*=============================================================*/
  725. /* Put the interrupt and function number into the separator    */
  726. /* line just above the intlist entry preceding the cursor pos  */
  727. /*=============================================================*/
  728.  
  729. int number_one_int()
  730. {
  731.    char func_num[13] ;            /* 2->int, 4->AX, 6->extra reg, NUL */
  732.    int oldpoint ;
  733.    
  734.    while (to_separator_line(-1))    /* find previous separator line */
  735.       {
  736.       oldpoint = point ;
  737.       if (grab_entry_number(func_num))    /* does it belong to an intlist entry? */
  738.      {                /*   if yes, success, else try again */
  739.      point = oldpoint + 11 ;    /* skip NL and first ten dashes */
  740.      delete(point,point+12) ;    /* replace 12 dashes by the function */
  741.      stuff(func_num) ;        /*   number and extra register */
  742.      point = oldpoint + 9 ;        /* back to category letter position */
  743.      return 1 ;
  744.      }
  745.       point = oldpoint ;
  746.       }
  747.    return 0 ;                /* if we get here, we failed */
  748. }
  749.  
  750. /*=============================================================*/
  751. /* Put the interrupt and function number into the separator    */
  752. /* line just above one or more intlist entries preceding the   */
  753. /* current cursor position, letting user know of progress      */
  754. /*=============================================================*/
  755.  
  756. command number_int() on intlist_tab[FKEY(12)]
  757. {
  758.    int i, hit_top = 0 ;
  759.    
  760.    for (i = 0 ; i < iter ; i++)
  761.       {
  762.       if (!number_one_int())
  763.      {
  764.      hit_top = 1 ;
  765.      say("No prior entry.") ;
  766.      break ;
  767.      }
  768.       if (((i+1) % NUMBER_INT_PROGRESS_INTERVAL) == 0)
  769.      say("%4d...",i+1) ;
  770.       }
  771.    if (iter > 1 && !hit_top)
  772.       say("Done.") ;
  773.    iter = 1 ;
  774. }
  775.  
  776. /*=============================================================*/
  777. /*=============================================================*/
  778.  
  779. int line_has_see_also()
  780. {
  781.    int len ;
  782.    
  783.    to_begin_line() ;
  784.    if ((len = parse_string(1,".*%([sS]ee ",NULL)) != 0)
  785.       {
  786.       point += len ;        /* go to start of cross-reference */
  787.       point += parse_string(1,"also ",NULL) ;
  788.       if (parse_string(1,"INT [0-9A-F]",NULL) ||
  789.       parse_string(1,"A[XHL] =",NULL)
  790.      )
  791.      {
  792.      point++ ;        /* move into reference */
  793.      return 1 ;
  794.      }
  795.       }
  796.    return 0 ;
  797. }
  798.  
  799. /*=============================================================*/
  800. /*=============================================================*/
  801.  
  802. int grab_int_reference(ref)
  803. char *ref ;
  804. {
  805.    int begin, start = point ;
  806.    
  807.    re_search(-1,"[, \t\n]") ;    /* backup to start of reference */
  808.    if (curchar() == '\n')    /* start of line? */
  809.       re_search(1,":[ \t]") ;    /* skip the SeeAlso: */
  810.    else if (character(point-1) == 'T' && character(point-2) == 'N')
  811.       point -= 3 ;
  812.    else
  813.       point++ ;            /* back to start of reference */
  814.    begin = point ;
  815.    re_search(1,"[,\n\"]") ;    /* find end of INT-spec */
  816.    point-- ;
  817.    if (curchar() == '\"')    /* extra string at end of INT-spec? */
  818.       {
  819.       point++ ;
  820.       re_search(1,"[\"\n]") ;    /* if yes, run to end of line or string */
  821.       }
  822.    grab(begin,point,ref) ;
  823.    point = start ;
  824.    return 0 ;
  825. }
  826.  
  827. /*=============================================================*/
  828. /*=============================================================*/
  829.  
  830. int parse_int_name(entry_name,id,extra_string)
  831. char *entry_name, *id, *extra_string ;
  832. {
  833.    int start = point ;
  834.    int i ;
  835.    char c, *last ;
  836.  
  837.    for (i = strlen(entry_name)-1 ; i >= 0 ; i--)
  838.       entry_name[i] = toupper(entry_name[i]) ;
  839.    strcpy(id,"------------") ;
  840.    if (strncmp(entry_name,"INT ",4) == 0)
  841.       {
  842.       id[0] = entry_name[4] ;
  843.       id[1] = entry_name[5] ;
  844.       entry_name += 6 ;
  845.       if (entry_name[0] == '/')
  846.      entry_name++ ;
  847.       }
  848.    else if (to_separator_line(-1))
  849.       {
  850.       id[0] = character(point+11) ;
  851.       id[1] = character(point+12) ;
  852.       }
  853.    point = start ;
  854.    c = entry_name[1] ;
  855.    if (entry_name[0] == 'A' && (c == 'X' || c == 'H' || c == 'L'))
  856.       {
  857.       entry_name += 2 ;
  858.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  859.      entry_name++ ;
  860.       if (entry_name[0] == '=')
  861.      entry_name++ ;
  862.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  863.      entry_name++ ;
  864.       if (c != 'L')
  865.      {
  866.          id[2] = entry_name[0] ;
  867.          id[3] = entry_name[1] ;
  868.      }
  869.       if (c == 'X')
  870.      {
  871.      id[4] = entry_name[2] ;
  872.      id[5] = entry_name[3] ;
  873.      entry_name += 4 ;
  874.      }
  875.       else
  876.      {
  877.      if (c == 'L')
  878.         {
  879.         id[2] = entry_name[0] ;
  880.         id[3] = entry_name[1] ;
  881.         }
  882.      entry_name += 2 ;
  883.      }
  884.       if (entry_name[0] == 'H')
  885.      entry_name++ ;
  886.       if (entry_name[0] == '/')
  887.      entry_name++ ;
  888.       }
  889.    if (index("ABCDES",entry_name[0]) && index("HILPSXF",entry_name[1]))
  890.       {
  891.       id[6] = entry_name[0] ;
  892.       c = id[7] = entry_name[1] ;
  893.       entry_name += 2 ;
  894.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  895.      entry_name++ ;
  896.       if (entry_name[0] == '=')
  897.      entry_name++ ;
  898.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  899.      entry_name++ ;
  900.       id[8] = entry_name[0] ;
  901.       id[9] = entry_name[1] ;
  902.       if (c != 'H' && c != 'L' && (c != 'F' || entry_name[2] != 'h'))
  903.      {
  904.      id[10] = entry_name[2] ;
  905.      id[11] = entry_name[3] ;
  906.      entry_name += 4 ;
  907.      }
  908.       else
  909.      entry_name += 2 ;
  910.       if (entry_name[0] == 'H')
  911.      entry_name++ ;
  912.       if (entry_name[0] == '/')
  913.      entry_name++ ;
  914.       }
  915.    if (entry_name[0] == '\"')
  916.       {
  917.       entry_name++ ;
  918.       strcpy(extra_string,entry_name) ;
  919.       last = index(extra_string,'\"') ;
  920.       if (last)
  921.      *last = '\0' ;
  922.       }
  923.    else
  924.       extra_string[0] = '\0' ;
  925.    return 0 ;
  926. }
  927.  
  928. /*=============================================================*/
  929. /*=============================================================*/
  930.  
  931. int hex2_to_int(c1,c2)
  932. char c1, c2 ;
  933. {
  934.    if (c1 >= '0' && c1 <= '9')
  935.       c1 -= '0' ;
  936.    else if (c1 >= 'A' && c1 <= 'F')
  937.       c1 = c1 - 'A' + 10 ;
  938.    else if (c1 >= 'a' && c1 <= 'f')
  939.       c1 = c1 - 'a' + 10 ;
  940.    else
  941.       return -1 ;
  942.    if (c2 >= '0' && c2 <= '9')
  943.       c2 -= '0' ;
  944.    else if (c2 >= 'A' && c2 <= 'F')
  945.       c2 = c2 - 'A' + 10 ;
  946.    else if (c2 >= 'a' && c2 <= 'f')
  947.       c2 = c2 - 'a' + 10 ;
  948.    else
  949.       return -1 ;
  950.    return 16*c1 + c2 ;
  951. }
  952.  
  953. /*=============================================================*/
  954. /*=============================================================*/
  955.  
  956. char hex_digit(val)
  957. int val ;
  958. {
  959.    if (val < 0)
  960.       return '-' ;
  961.    else
  962.       return (val > 9) ? ('A' + val - 10) : ('0' + val) ;
  963. }
  964.  
  965. /*=============================================================*/
  966. /*=============================================================*/
  967.  
  968. int scan_for_entry(entry,extra_str,first_entry)
  969. char *entry, *extra_str ;
  970. int *first_entry ;
  971. {
  972.    int bestcount = 0 ;
  973.    int bestmatch = -1 ;
  974.  
  975.    if (extra_str) extra_str = 0 ;  /* for now, to avoid compiler warning */
  976.    *first_entry = 0 ;
  977.    /* scan for the first entry for the desired interrupt number */
  978.    while (to_separator_line(1))
  979.       {
  980.       point += 2 ;
  981.       if (character(point) == entry[0] && character(point+1) == entry[1])
  982.      break ;
  983.       nl_forward() ;
  984.       }
  985.    /* now scan through the entries for the given interrupt number */
  986.    while (to_separator_line(1))
  987.       {
  988.       int i ;
  989.       char buf[14] ;
  990.       point += 2 ;
  991.       grab(point,point+12,buf) ;
  992.       if ((buf[0] != entry[0] || buf[1] != entry[1]) &&
  993.       (buf[0] != '-' && buf[1] != '-'))
  994.      break ;            /* ran out of entries... */
  995.       for (i = 2 ; i <= 12 ; i++)
  996.      {
  997.      if (buf[i] != entry[i])
  998.         break ;
  999.      }
  1000.       if (i > bestcount)
  1001.      {
  1002.      bestcount = i ;
  1003.      bestmatch = point ;
  1004.      if (i > 12)
  1005.         break ;            /* found an exact match */
  1006.      }
  1007.       nl_forward() ;
  1008.       }
  1009.    if (bestmatch == -1)
  1010.       return 0 ;            /* we failed */
  1011.    else
  1012.       {
  1013.       *first_entry = bestmatch ;
  1014.       point = bestmatch ;        /* back to best-matching entry */
  1015.       nl_forward() ;
  1016.       return 1 ;            /* we were successful */
  1017.       }
  1018. }
  1019.  
  1020. /*=============================================================*/
  1021. /*=============================================================*/
  1022.  
  1023. int goto_entry(entry_name)
  1024. char *entry_name ;
  1025. {
  1026.    char int_id[13], extra_string[60] ;
  1027.    int start = point, first_entry ;
  1028.    int int_num, curr_int ;
  1029.    char search_str[22] ;
  1030.    
  1031.    parse_int_name(entry_name,int_id,extra_string) ;
  1032.    int_num = hex2_to_int(int_id[0],int_id[1]) ;
  1033.    if (to_separator_line(-1))
  1034.       {
  1035.       if (character(point+11) == '-')
  1036.      curr_int = -1 ;
  1037.       else
  1038.      curr_int = hex2_to_int(character(point+11),character(point+12)) ;
  1039.       if (int_num <= 0)
  1040.      point = 0 ;        /* go to top of file */
  1041.       else
  1042.      {
  1043.      if (curr_int <= 0)
  1044.         point = 0 ;        /* go to top of file */
  1045.      strcpy(search_str,"--------.-") ;
  1046.      search_str[10] = hex_digit((int_num-1) / 16) ;
  1047.      search_str[11] = hex_digit((int_num-1) % 16) ;
  1048.      search_str[12] = '\0' ;
  1049.      if (!re_search( (int_num<=curr_int)?-1:1, search_str))
  1050.         {
  1051.         say("%s not found.",entry_name) ;
  1052.         iter = 1 ;
  1053.         return 0 ;
  1054.         }
  1055.      to_begin_line() ;
  1056.      }
  1057.       }
  1058.    else
  1059.       point = 0 ;
  1060.    if (!scan_for_entry(int_id,extra_string,&first_entry))
  1061.       {
  1062.       say("%s not found.",entry_name) ;
  1063.       if (first_entry)
  1064.      {
  1065.      mark = start ;
  1066.      point = first_entry ;
  1067.      }
  1068.       else
  1069.      point = start ;
  1070.       }
  1071.    if (has_arg)
  1072.      iter = 1 ;                /* don't search repeatedly */
  1073.    return 0 ;
  1074. }
  1075.  
  1076. /*=============================================================*/
  1077. /*=============================================================*/
  1078.  
  1079. command goto_int() on intlist_tab[FCTRL(12)]
  1080. {
  1081.    char entry_name[60], def_entry[60] ;
  1082.    int start = point ;
  1083.  
  1084.    to_begin_line() ;
  1085.    if (parse_string(1,"SeeAlso: ",NULL) != 0)
  1086.       {
  1087.       point += 9 ;        /* skip the SeeAlso: */
  1088.       if (point < start)    /* if we were originally to the right of     */
  1089.      point = start ;    /* current position, go back to original pos */
  1090.       grab_int_reference(def_entry) ;
  1091.       get_strdef(entry_name,"Goto Interrupt",def_entry) ;
  1092.       }
  1093.    else if (line_has_see_also())
  1094.       {
  1095.       grab_int_reference(def_entry) ;
  1096.       get_strdef(entry_name,"Goto Interrupt",def_entry) ;
  1097.       }
  1098.    else
  1099.       get_string(entry_name,"Goto Interrupt: ") ;
  1100.    point = start ;
  1101.    goto_entry(entry_name) ;
  1102.    if (has_arg)
  1103.       iter = 1 ;
  1104. }
  1105.  
  1106. /*=============================================================*/
  1107. /*=============================================================*/
  1108.  
  1109. void maybe_append_table_number()
  1110. {
  1111.    if (parse_string(1,".*\t%(Table ",0) == 0)
  1112.       {
  1113.       int matchsize ;
  1114.       /* if the pattern didn't match, there is no table number, */
  1115.       /* so add it */
  1116.       to_end_line() ;
  1117.       matchsize = parse_string(-1,"[ \t]+",0) ;
  1118.       if (matchsize)
  1119.      delete(point-matchsize,point) ;
  1120.       stuff("\t") ;
  1121.       insert_table_counter() ;
  1122.       }
  1123. }
  1124.  
  1125. /*=============================================================*/
  1126. /*=============================================================*/
  1127.  
  1128. void fix_unnumbered_tables()
  1129. {
  1130.    spot start = alloc_spot(1) ;
  1131.    
  1132.    *start = point ;
  1133.    point = 0 ;
  1134.    while (search(1,"\n\n"))
  1135.       {
  1136.       switch(curchar())
  1137.      {
  1138.      case 'C':
  1139.         if (parse_string(1,"Call ") != 0)
  1140.            {
  1141.            /* we got Call..., we know it doesn't have a table number */
  1142.            insert_table_counter() ;
  1143.            stuff("\n") ;
  1144.            }
  1145.         break ;
  1146.      case 'V':
  1147.         if (parse_string(1,"Values ") != 0)
  1148.            {
  1149.            /* we know this Values... doesn't have a table number */
  1150.            insert_table_counter() ;
  1151.            stuff("\n") ;
  1152.            }
  1153.         break ;
  1154.      case 'B':
  1155.         if (parse_string(1,"Bitfields ",0) == 0)
  1156.            break ;
  1157.         nl_forward() ;    /* skip to start of next line */
  1158.         maybe_append_table_number() ;
  1159.         break ;
  1160.      case 'F':
  1161.         if (parse_string(1,"Format ",0) == 0)
  1162.            break ;
  1163.         nl_forward() ;    /* skip to start of next line */
  1164.         maybe_append_table_number() ;
  1165.         break ;
  1166.      default:
  1167.         /* not a table header, so ignore it */
  1168.         break ;
  1169.      }
  1170.       }
  1171.    point = *start ;
  1172.    free_spot(start) ;
  1173. }
  1174.  
  1175. /*=============================================================*/
  1176. /*=============================================================*/
  1177.  
  1178. short *gather_table_numbers(new_numbers)
  1179. short *new_numbers ;
  1180. {
  1181.    int tcount[6] ;
  1182.    char counter[5] ;
  1183.    int old_number ;
  1184.    int table_type ;
  1185.    spot start = alloc_spot(1) ;
  1186.    save_var case_fold = 0 ;
  1187.    
  1188.    tcount[0] = tcount[1] = tcount[2] = tcount[3] = tcount[4] = tcount[5] = 0 ;
  1189.    *start = point ;
  1190.    point = 0 ;
  1191.    while (search(1,"(Table "))
  1192.       {
  1193.       char *tbl ;
  1194.       int table_offset ;
  1195.       grab(point,point+4,counter) ;
  1196.       tbl = index(table_ID_letters,counter[0]) ;
  1197.       if (tbl)
  1198.      table_offset = (tbl-table_ID_letters) ;
  1199.       else
  1200.      table_offset = 0 ;
  1201.       old_number = strtoi(counter+1,10) + 1000*table_offset ;
  1202.       table_type = (table_offset > 9) ? (table_offset-9) : 0 ;
  1203.       new_numbers[old_number] = (short)++(tcount[table_type]) ;
  1204.       }
  1205.    point = *start ;
  1206.    free_spot(start) ;
  1207.    return new_numbers ;
  1208. }
  1209.  
  1210. /*=============================================================*/
  1211. /*=============================================================*/
  1212.  
  1213. int adjust_table_numbers(new_numbers, dangling)
  1214. short *new_numbers ;
  1215. int dangling ;
  1216. {
  1217.    char counter[5] ;
  1218.    int old_number ;
  1219.    int old_type ;
  1220.    char *tbl ;
  1221.    int table_offset ;
  1222.    spot start = alloc_spot(1) ;
  1223.    
  1224.    *start = point ;
  1225.    point = 0 ;
  1226.    while (search(1,"(Table "))
  1227.       {
  1228.       grab(point,point+4,counter) ;
  1229.       tbl = index(table_ID_letters,counter[0]) ;
  1230.       if (tbl)
  1231.      table_offset = 1000*(tbl-table_ID_letters) ;
  1232.       else
  1233.      table_offset = 0 ;
  1234.       old_number = strtoi(counter+1,10) + table_offset ;
  1235.       old_type = (counter[0] >= '0' && counter[0] <= '9') ? 0 : counter[0] ;
  1236.       if (old_number > 0)
  1237.      {
  1238.      delete(point,point+4) ;
  1239.      if (old_type)
  1240.         bprintf("%c%03d",old_type,new_numbers[old_number]%1000) ;
  1241.      else
  1242.         bprintf("%04d",new_numbers[old_number]) ;
  1243.      }
  1244.       }
  1245.    point = 0 ;
  1246.    while (re_search(1,"[, \t]%#[0-9CFMPR][0-9][0-9][0-9]"))
  1247.       {
  1248.       grab(point-4,point,counter) ;
  1249.       tbl = index(table_ID_letters,counter[0]) ;
  1250.       if (tbl)
  1251.      table_offset = 1000*(tbl-table_ID_letters) ;
  1252.       else
  1253.      table_offset = 0 ;
  1254.       old_number = strtoi(counter+1,10) + table_offset ;
  1255.       old_type = (counter[0] >= '0' && counter[0] <= '9') ? 0 : counter[0] ;
  1256.       if (old_number > 0)
  1257.      {
  1258.      if (new_numbers[old_number])
  1259.         {
  1260.         delete(point-4,point) ;
  1261.         if (old_type)
  1262.            bprintf("%c%03d",old_type,new_numbers[old_number]) ;
  1263.         else
  1264.            bprintf("%04d",new_numbers[old_number]) ;
  1265.         }
  1266.      else /* dangling xref */
  1267.         {
  1268.         dangling++ ;
  1269.         point -= 4 ;
  1270.         stuff("?") ;
  1271.         point += 4 ;
  1272.         }
  1273.      }
  1274.       }
  1275.    point = *start ;
  1276.    free_spot(start) ;
  1277.    return dangling ;
  1278. }
  1279.  
  1280. /*=============================================================*/
  1281. /*=============================================================*/
  1282.  
  1283. int get_list_file(list_file)
  1284. char *list_file ;
  1285. {
  1286.    char abs_filename[FNAMELEN] ;
  1287.    strcpy(abs_filename,list_file) ;
  1288.    absolute(abs_filename) ;
  1289.    return find_it(abs_filename,1) ;
  1290. }
  1291.  
  1292. /*=============================================================*/
  1293. /*=============================================================*/
  1294.  
  1295. command renumber_tables()
  1296. {
  1297.    short *new_numbers ;
  1298.    int num_tables ;
  1299.    int dangling ;
  1300.    int i ;
  1301.    
  1302.    for (i = 0 ; list_files[i] ; i++)
  1303.       {
  1304.       if (get_list_file(list_files[i]) == 0)
  1305.      {
  1306.      say("Renumber Pass 1: numbering unnumbered tables (%s)",
  1307.          list_files[i]) ;
  1308.      fix_unnumbered_tables() ;
  1309.      }
  1310.       else
  1311.      say("Renumber Pass 1: forced to skip %s") ;
  1312.       }
  1313.    num_tables = 1000*strlen(table_ID_letters) ;
  1314.    new_numbers = (short*)malloc(num_tables*sizeof(short)) ;
  1315.    if (!new_numbers)
  1316.       {
  1317.       say("Out of memory!") ;
  1318.       return ;
  1319.       }
  1320.    for (i = 0 ; i < num_tables ; i++)
  1321.       new_numbers[i] = 0 ;
  1322.    for (i = 0 ; list_files[i] ; i++)
  1323.       {
  1324.       if (get_list_file(list_files[i]) == 0)
  1325.      {
  1326.      say("Renumber Pass 2: gathering table numbers (%s)",
  1327.          list_files[i]) ;
  1328.      gather_table_numbers(new_numbers) ;
  1329.      }
  1330.       else
  1331.      say("Renumber Pass 2: forced to skip %s") ;
  1332.       }
  1333.    dangling = 0 ;
  1334.    for (i = 0 ; list_files[i] ; i++)
  1335.       {
  1336.       if (get_list_file(list_files[i]) == 0)
  1337.      {
  1338.      say("Renumber Pass 3: adjusting table numbers (%s)",
  1339.          list_files[i]) ;
  1340.      dangling = adjust_table_numbers(new_numbers,dangling) ;
  1341.      }
  1342.       else
  1343.      say("Renumber Pass 3: forced to skip %s") ;
  1344.       }
  1345.    free(new_numbers) ;
  1346.    if (dangling)
  1347.       say("%d dangling cross-references, search for '#?'",dangling) ;
  1348.    else
  1349.       say("Done") ;
  1350. }
  1351.  
  1352. /*=============================================================*/
  1353. /*=============================================================*/
  1354.  
  1355. command make_distribution()
  1356. {
  1357.    int i ;
  1358.    
  1359.    for (i = 0 ; list_files[i] ; i++)
  1360.       {
  1361.       /* switch to proper buffer, or load if not yet in a buffer */
  1362.       if (get_list_file(list_files[i]) == 0)
  1363.      {
  1364.      say("Setting divider lines (%s)",list_files[i]) ;
  1365.      point = size() ;
  1366.      while (point > 0)
  1367.         if (!number_one_int())
  1368.            break ;
  1369.      }
  1370.       else
  1371.      say("Forced to skip %s !",list_files[i]) ;
  1372.       }
  1373.    for (i = 0 ; list_files[i] ; i++)
  1374.       {
  1375.       /* switch to proper buffer, or load if not yet in a buffer */
  1376.       if (get_list_file(list_files[i]) == 0)
  1377.      {
  1378.      say("Tabifying file (%s)",list_files[i]) ;
  1379.      mark = 0 ;
  1380.      point = size() ;
  1381.      tabify_region() ;
  1382.      }
  1383.       }
  1384.    renumber_tables() ;
  1385.    save_all_buffers() ;
  1386.    say("Ready for distribution") ;
  1387.    point = 0 ;
  1388.    /* !!! should also split main list automatically */
  1389. }
  1390.  
  1391. /*=============================================================*/
  1392. /*=============================================================*/
  1393.  
  1394. void find_table_counter()
  1395. {
  1396.    save_var point = (size() > 10000) ? size() - 10000 : 0 ;
  1397.  
  1398.    search(1,"Highest Table Number = ") ;
  1399.    table_counter = alloc_spot(1) ;
  1400. }
  1401.  
  1402. /*=============================================================*/
  1403. /*  Coloring functions for Epsilon v7.0+               */
  1404. /*=============================================================*/
  1405.  
  1406. #if EELVERSION >= 70
  1407. int int_recolor_range(from, to)
  1408. int from, to ;
  1409. {
  1410.    if (from >= to)
  1411.       return to ;
  1412.    set_character_color(from,to,-1) ;
  1413.    save_var point, matchstart, matchend ;
  1414.    point = from ;
  1415.    if (to > size())
  1416.       to = size() ;
  1417.    while (point < to)
  1418.       {
  1419.       int start = point ;
  1420.       int len ;
  1421.       char c = curchar() ;
  1422.       if (c >= 'A' && c <= 'V')
  1423.      {
  1424.      if (parse_string(1,table_headers,NULL) != 0)
  1425.         {
  1426.         nl_forward() ;
  1427.         point-- ;
  1428.         set_character_color(start,point,color_class c_comment) ;
  1429.         }
  1430.      else if ((len = parse_string(1,all_sections,NULL)) > 0)
  1431.         set_character_color(start,start+len,color_class c_function) ;
  1432.      }
  1433.       else if (c == '\t' &&
  1434.            (len = parse_string(1,indented_sections,NULL)) != 0)
  1435.      {
  1436.      while (curchar() == '\t')
  1437.         {
  1438.         point++ ;
  1439.         len-- ;
  1440.         }
  1441.      set_character_color(point,point+len,color_class c_function) ;
  1442.      }
  1443.       nl_forward() ;
  1444.       }
  1445.    return point ;
  1446. }
  1447. #endif /* Epsilon v7.0+ */
  1448.  
  1449. #if EELVERSION >= 70
  1450. int int_recolor_from_here(safe)
  1451. int safe ;
  1452. {
  1453.    save_var point ;
  1454.    if (safe != point)
  1455.       {
  1456.       to_begin_line() ;            /* start of line is always 'safe' */
  1457.       }
  1458.    return point ;
  1459. }
  1460. #endif /* Epsilon v7.0+ */
  1461.  
  1462. /*=============================================================*/
  1463. /* Put the current buffer into IntList major mode           */
  1464. /*=============================================================*/
  1465.  
  1466. command intlist_mode()
  1467. {
  1468.    mode_keys = intlist_tab ;
  1469.    intlist_tab[')'] = intlist_tab[']'] = (short) show_matching_delimiter;
  1470.    delete_hacking_tabs = 0 ;
  1471.    major_mode = strsave("IntList") ;
  1472.    auto_indent = 0 ;
  1473.    margin_right = 79 ;
  1474.    want_backups = 1 ;
  1475.    undo_size = 200000 ;     /* less than default 500,000 since list is so big */
  1476.    find_table_counter() ;
  1477. #if EELVERSION >= 70
  1478.    recolor_range = int_recolor_range ;
  1479.    recolor_from_here = int_recolor_from_here ;
  1480.    if (want_code_coloring)
  1481.       when_setting_want_code_coloring() ;
  1482. #endif /* Epsilon v7.0+ */
  1483.    make_mode() ;
  1484. }
  1485.  
  1486. when_loading()
  1487. {
  1488.    char *curbuf ;
  1489.    int i ;
  1490.    
  1491.    want_backups = want_backups.default = 1 ;
  1492.    strcpy(backup_name,"%pbak/%b%e") ;        /* put backups in BAK subdir */
  1493.    one_window() ;
  1494.    intlist_mode() ;
  1495.    if (exist("interrup.1st"))
  1496.       {
  1497.       curbuf = bufname ;
  1498.       bufname = "interrup.1st" ;
  1499.       intlist_mode() ;
  1500.       want_code_coloring = 0 ;
  1501.       when_setting_want_code_coloring() ;
  1502.       bufname = curbuf ;
  1503.       }
  1504.    for (i = 0 ; list_files[i] ; i++)
  1505.       {
  1506.       if (exist(list_files[i]))
  1507.      {
  1508.      curbuf = bufname ;
  1509.      bufname = list_files[i] ;
  1510.      intlist_mode() ;
  1511.      bufname = curbuf ;
  1512.      }
  1513.       }
  1514. #if EELVERSION >= 70
  1515.    strcpy(mode_end," %d%p%S%>C%c") ;
  1516. #endif /* Epsilon v7.0+ */
  1517. #if EELVERSION >= 60 && EELVERSION < 70
  1518.    strcpy(mode_end," %d%p%S") ;
  1519. #endif /* Epsilon v6.x */
  1520. }
  1521.  
  1522. /*=============================================================*/
  1523. /* automagically switch into interrupt list mode on .LST and .1ST files */
  1524.  
  1525. suffix_lst()   { intlist_mode(); }
  1526. suffix_1st()   { intlist_mode(); }
  1527.  
  1528. /* end of file intlist.e */
  1529.